import {_decorator, Camera, Component, find, game, Game, Node, Vec3,} from 'cc';
import {StageManager} from "db://assets/scripts/game/StageManager";
import {GameCameraController} from "db://assets/scripts/game/GameCameraController";
import {EventType} from "db://assets/scripts/common/EventType";
import {EventManager} from "db://assets/scripts/common/EventManager";
import {CSVManager} from "db://assets/scripts/common/CSVManager";
import {UIManager} from "db://assets/scripts/common/UIManager";
import {PoolManager} from "db://assets/scripts/common/PoolManager";
import {PlayerDataManager} from "db://assets/scripts/common/PlayerDataManager";
import {AudioManager} from "db://assets/scripts/common/AudioManager";
import {StorageManager} from "db://assets/scripts/common/StorageManager";
import {StorageKey} from "db://assets/scripts/common/StorageKey";
import {Chapter} from "db://assets/scripts/data/model/Chapter";
import {ChapterManager} from "db://assets/scripts/game/ChapterManager";
import {GameStateProxy} from "db://assets/scripts/game/GameStateProxy";
import {GameSpeedProxy} from "db://assets/scripts/game/GameSpeedProxy";
import {GamePreloadProxy} from "db://assets/scripts/game/GamePreloadProxy";
import {GameWarpGateProxy} from "db://assets/scripts/game/GameWarpGateProxy";
import {GameGoldProxy} from "db://assets/scripts/game/GameGoldProxy";
import {GameGetMonsterProxy} from "db://assets/scripts/game/GameGetMonsterProxy";
import {GamePlayerProxy} from "db://assets/scripts/game/GamePlayerProxy";
import {GameState} from "db://assets/scripts/game/GameState";
import {GameBossProxy} from "db://assets/scripts/game/GameBossProxy";

const {ccclass, property} = _decorator;

/**
 * 游戏管理脚本
 */
@ccclass('GameManager')
export class GameManager extends Component {
    /**
     * 相机脚本
     */
    @property(GameCameraController)
    public gameCameraController: GameCameraController;
    /**
     * 关卡脚本
     */
    @property(StageManager)
    public stageManager: StageManager;
    /**
     * 主光源
     */
    @property(Node)
    public lightNode: Node;

    /**
     * 主相机
     */
    public mainCamera: Camera;
    /**
     * 特效节点
     */
    public effectManagerNode: Node;
    /**
     * 地图节点
     */
    public mapManagerNode: Node;

    /**
     * 层级信息
     */
    public chapter: Chapter;

    /**
     * 主光源节点初始世界坐标
     */
    private mainLightOriginWorldPosition: Vec3;
    /**
     * 主光源和玩家的向量差
     */
    private mainLightOffsetWorldPosition: Vec3 = new Vec3();

    /**
     * 游戏状态代理
     */
    public gameStateProxy: GameStateProxy;
    /**
     * 游戏速度代理
     */
    public gameSpeedProxy: GameSpeedProxy;
    /**
     * 游戏预加载代理
     */
    public gamePreloadProxy: GamePreloadProxy;
    /**
     * 游戏传送门代理
     */
    public gameWarpGateProxy: GameWarpGateProxy;
    /**
     * 游戏添加金币代理
     */
    public gameGoldProxy: GameGoldProxy;
    /**
     * 游戏获取怪物代理
     */
    public gameGetMonsterProxy: GameGetMonsterProxy;
    /**
     * 游戏玩家代理
     */
    public gamePlayerProxy: GamePlayerProxy;
    /**
     * 游戏Boss代理
     */
    public gameBossProxy: GameBossProxy;

    /**
     * 游戏管理器实例
     */
    private static instance: GameManager;

    /**
     * 获取游戏管理器实例
     */
    public static getInstance(): GameManager {
        return this.instance;
    }

    onEnable() {
        // 系统事件
        game.on(Game.EVENT_HIDE, this.offlineTime, this);

        // 自定义事件
        EventManager.on(EventType.ON_GAME_INIT, this.onGameInit, this);
        EventManager.on(EventType.ON_GAME_PAUSE, this.onGamePause, this);
        EventManager.on(EventType.ON_GAME_OVER, this.onGameOver, this);
        EventManager.on(EventType.REFRESH_FLOOR, this.refreshFloor, this);
        EventManager.on(EventType.RECYCLE_ALL, this.recycleAll, this);
    }

    onDisable() {
        // 系统事件
        game.off(Game.EVENT_HIDE, this.offlineTime, this);

        // 自定义事件
        EventManager.off(EventType.ON_GAME_INIT, this.onGameInit, this);
        EventManager.off(EventType.ON_GAME_PAUSE, this.onGamePause, this);
        EventManager.off(EventType.ON_GAME_OVER, this.onGameOver, this);
        EventManager.off(EventType.REFRESH_FLOOR, this.refreshFloor, this);
        EventManager.off(EventType.RECYCLE_ALL, this.recycleAll, this);
    }

    /**
     * 记录离线时间
     */
    private offlineTime() {
        StorageManager.getInstance().setData(StorageKey.OFFLINE_TIME, Date.now().toString());
    }

    start() {
        console.log("游戏初始化开始...");
        // 初始化游戏管理器实例
        GameManager.instance = this;

        this.mainCamera = this.gameCameraController.getComponent(Camera);
        this.mapManagerNode = find("mapManager");
        this.effectManagerNode = find("effectManager");

        this.mainLightOriginWorldPosition = this.lightNode.worldPosition.clone();

        // 初始化音频
        AudioManager.getInstance();
        // 初始化数据
        CSVManager.getInstance();
        // todo 初始化玩家
        // todo 初始化玩家数据

        // 初始化代理
        this.gameStateProxy = new GameStateProxy(this);
        this.gameSpeedProxy = new GameSpeedProxy(this);
        this.gamePreloadProxy = new GamePreloadProxy(this);
        this.gameWarpGateProxy = new GameWarpGateProxy(this);
        this.gameGoldProxy = new GameGoldProxy(this);
        this.gameGetMonsterProxy = new GameGetMonsterProxy(this);
        this.gamePlayerProxy = new GamePlayerProxy(this);
        this.gameBossProxy = new GameBossProxy(this);
    }

    update(deltaTime: number) {
        // 光源跟随玩家人物移动
        if (this.gamePlayerProxy.getPlayerController()
            && this.gamePlayerProxy.getPlayerNode()
            && this.gameStateProxy.getGameState() !== GameState.OVER) {
            Vec3.subtract(this.mainLightOffsetWorldPosition, this.gamePlayerProxy.getPlayerNode().worldPosition, this.mainLightOriginWorldPosition);
            this.mainLightOffsetWorldPosition.set(this.mainLightOffsetWorldPosition.x, 0, this.mainLightOffsetWorldPosition.z);
            this.lightNode.setWorldPosition(this.mainLightOffsetWorldPosition.add(this.mainLightOriginWorldPosition));
        }
    }

    /**
     * 初始化游戏
     */
    private onGameInit() {
        // 当前在第几层
        let floor = PlayerDataManager.getInstance().getPlayer().floor;
        // 一共有多少层
        let totalFloor = ChapterManager.getInstance().getChapters().length;
        // 游戏通关后从倒数第10关开始循环(61-70)
        if (floor > totalFloor) {
            floor = (totalFloor - 10) + (floor - totalFloor) % 10;
        }
        // 初始化当前层级信息
        this.chapter = ChapterManager.getInstance().getChapter(floor);

        // 隐藏传送门
        EventManager.dispatchEvent(EventType.HIDE_WARP_GATE);

        // 暂停所有音频
        AudioManager.getInstance().pauseAll();

        // 加载中面板
        UIManager.getInstance().showDialog("loading/loadingPanel", [() => {
            // 刷新层级
            this.refreshFloor();
        }]);
    }

    /**
     * 游戏暂停
     */
    private onGamePause() {
        // 改变游戏状态
        this.gameStateProxy.setGameState(GameState.PAUSE);
    }

    /**
     * 游戏结束
     */
    private onGameOver() {
        // 游戏结束
        if (this.gameStateProxy.getGameState() === GameState.OVER) {
            return;
        }

        // 游戏胜利
        if (this.gameStateProxy.getWin()) {
            // 隐藏战斗面板
            UIManager.getInstance().hideDialog("fight/fightPanel");
            // 改变游戏状态
            this.gameStateProxy.setGameState(GameState.OVER);
            // 回收所有节点
            this.recycleAll();

            // 下一层
            let nextFloor = PlayerDataManager.getInstance().getPlayer().floor + 1;
            PlayerDataManager.getInstance().getPlayer().floor = nextFloor;

            // 更新已解锁最高层级
            if (nextFloor > PlayerDataManager.getInstance().getPlayer().heightFloor) {
                PlayerDataManager.getInstance().getPlayer().heightFloor = nextFloor;
            }

            // 游戏初始化
            EventManager.dispatchEvent(EventType.ON_GAME_INIT);
            return;
        }

        // 游戏失败，复活
        UIManager.getInstance().showDialog("revive/revivePanel", [() => {
            if (this.gamePlayerProxy.getPlayerNode()) {
                PoolManager.getInstance().putNode(this.gamePlayerProxy.getPlayerNode());
                this.gamePlayerProxy.setPlayerNode(null);
                this.gamePlayerProxy.setPlayerController(null);
            }

            this.recycleAll();
        }]);
    }

    /**
     * 刷新关卡, 后期优化写法。。。
     */
    private refreshFloor() {
        // 每层随机一张地图
        let mapNames = this.chapter.mapName.split("#");
        // 地图名称
        let mapName = mapNames[Math.floor(Math.random() * mapNames.length)];

        this.gamePreloadProxy.preloadMonsterSkill(mapName, () => {
            this.recycleAll();
            this.loadMap(mapName, () => {
                //第一次进入或者失败后被销毁需要重新创建
                if (!this.gamePlayerProxy.getPlayerNode()) {
                    this.gamePlayerProxy.createPlayer();
                } else {
                    this.gamePlayerProxy.getPlayerController().preloadArrow(() => {
                        EventManager.dispatchEvent(EventType.HIDE_LOADING_PANEL, () => {
                            this.gamePlayerProxy.getPlayerController().resetPlayerState();
                        });
                    })
                }
            });
        });
    }

    /**
     * 加载关卡数据
     *
     * @param stageName 关卡名称
     * @param callback 回调
     */
    private loadMap(stageName: string, callback?: Function) {
        this.stageManager.buildStage(stageName, () => {
            callback && callback();
        })
    }

    /**
     * 回收怪兽, 武器，特效等
     */
    private recycleAll() {
        // 回收关卡
        this.stageManager.recycle();

        // 回收武器
        this.node.children.forEach((childNode: Node) => {
            if (childNode.name !== "player01") {
                PoolManager.getInstance().putNode(childNode);
            }
        });

        // 回收特效
        if (this.effectManagerNode.children.length) {
            PoolManager.getInstance().putNode(this.effectManagerNode.children[0]);
        }
    }
}